using namespace std;

#include "ProductorJugadorX.h"

int nroJugadorStatic = 0;

ProductorJugadorX::ProductorJugadorX(bool atributo) : Thread(atributo){
	this->nroJugador= CONST_CERO;
	this->conexion 	= NULL;
}

ProductorJugadorX::~ProductorJugadorX() {
	free(this);
}

//Seters
void ProductorJugadorX::setNroJugador(unsigned short int nroJugador){
	this->nroJugador = nroJugador;
	nroJugadorStatic = nroJugador;
}

void ProductorJugadorX::setConexion(Socket *conexion){
	this->conexion = conexion;
}

//Getters
t_jugador *ProductorJugadorX::getJugador(){
	return Partida::getInstance()->getJugadorXNro(nroJugador);
}

//Manejador de señales de interrupcion.
void ProductorJugadorX::signalHandler(int signal){
	if(signal == SIGFPE && nroJugadorStatic==1){
		//Informo la finalizacion por sysout
		cout << "[INFO] - Se cierra el hilo de escucha al jugador." << endl;
		//Cierro el thread.
		pthread_exit(NULL);
	} else if(signal == SIGILL && nroJugadorStatic == 2){
		//Informo la finalizacion por sysout
		cout << "[INFO] - Se cierra el hilo de escucha al jugador." << endl;
		//Cierro el thread.
		pthread_exit(NULL);
	}
}

void ProductorJugadorX::run (){
	/* Me attacho a la señal que envia el server para finalizar. */
	signal(SIGFPE, ProductorJugadorX::signalHandler);
	signal(SIGILL, ProductorJugadorX::signalHandler);
	signal(SIGURG, ProductorJugadorX::signalHandler);
	signal(SIGABRT, ProductorJugadorX::signalHandler);
	signal(SIGCLD, ProductorJugadorX::signalHandler);
	signal(SIGQUIT, ProductorJugadorX::signalHandler);
	signal(SIGIO,  ProductorJugadorX::signalHandler);

	/* Mientras el cliente este activo */
	while (Partida::getInstance()->isActivo() && Partida::getInstance()->getJugadorXNro(nroJugador)->conectado) {

		/* Recibo el comando del cliente como un puntero void */
		t_accion *accionRecibida = (t_accion *)(this->conexion->read(sizeof(t_accion), Partida::getInstance()->getJugadorXNro(nroJugador)->socket_id));

		/* Si no esta vacia la accion y la partida no esta parada, lo encolo en el singleton del juego. */
		if (accionRecibida != NULL)
			Partida::getInstance()->encolarAccionAProcesar(*accionRecibida);
		else{
			/* Sino muestro error */
			cout << "[AVISO] - Se descarta accion recibida "<< endl;
			Partida::getInstance()->getJugadorXNro(nroJugador)->conectado = CONST_FALSE;
		}

		usleep(50000);
	}

	//Cierro el thread.
	pthread_exit(NULL);
}
	
